package com.finalministry.db.dao.impl;

import java.util.List;

import com.finalministry.db.dao.AbstractDAO;
import com.finalministry.db.dao.DataAccessLayerException;
import com.finalministry.db.objects.address.Address;

@SuppressWarnings("rawtypes")
public class AddressDAO extends AbstractDAO {

	private static final String TABLENAME = "address";

	public AddressDAO() {
		super();
	}

	/**
	 * Insert a new Address into the database.
	 * 
	 * @param Address
	 * @return persisted ID
	 * @throws DataAccessLayerException
	 */
	@SuppressWarnings("unchecked")
	public Address merge(Address address) throws DataAccessLayerException {

		return (Address) super.merge(address);
	}

	/**
	 * Delete a detached Address from the database.
	 * 
	 * @param Address
	 */
	public void delete(Address address) throws DataAccessLayerException {

		super.delete(address);
	}

	/**
	 * Find an Address by its primary key.
	 * 
	 * @param id
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public Address find(Long id) throws DataAccessLayerException {

		return (Address) super.find(Address.class, id);
	}

	/**
	 * Finds all Addresss in the database.
	 * 
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<Address> findAll() throws DataAccessLayerException {

		return super.findAll(Address.class);
	}

	/**
	 * Get table name
	 */
	@Override
	protected String getTableName() {

		return TABLENAME;
	}

	/**
	 * In Finalministry a address object is unique and should remain unique,
	 * therefore a NEW address is only created if it does not exist already,
	 * else the existing address id is returned.
	 * <p>
	 * By this method we ensure to be able to deliver coordinates to the address
	 * by external services without overusing them.
	 * 
	 * @param address
	 * @return
	 * @throws Exception
	 * 
	 *             <pre>
	 * public Long create(Address address) throws Exception {
	 * 
	 * 	System.out.println(&quot;Create address&quot;);
	 * 	System.out.println(&quot;First check if it already exist!&quot;);
	 * 
	 * 	Long preExistingId = getIdByAddressCriteria(address);
	 * 
	 * 	if (preExistingId != null) {
	 * 
	 * 		System.out.println(&quot;Found one pre existing address object with id = &quot; + preExistingId);
	 * 		return preExistingId;
	 * 	}
	 * 
	 * 	System.out.println(&quot;Found no pre existing one, I will create a new address object ...&quot;);
	 * 
	 * 	String insert = &quot;INSERT INTO ADDRESS (STREET,HOUSENUMBER,POSTALCODE,CITY,COUNTRYID,CREATED) VALUES(?,?,?,?,?,NOW())&quot;;
	 * 
	 * 	if (address.getCoordinate() != null) {
	 * 		insert = &quot;INSERT INTO ADDRESS (STREET,HOUSENUMBER,POSTALCODE,CITY,COUNTRYID,COORDINATES,CREATED) VALUES(?,?,?,?,?,ST_GeomFromText(?,4326),NOW())&quot;;
	 * 	}
	 * 
	 * 	PreparedStatement stmt = getConnection().getConnection().prepareStatement(insert);
	 * 
	 * 	stmt.setString(1, address.getStreet());
	 * 	stmt.setString(2, address.getHousenumber());
	 * 	stmt.setString(3, address.getPostalcode());
	 * 	stmt.setString(4, address.getCity());
	 * 	stmt.setLong(5, address.getCountry().getId());
	 * 
	 * 	if (address.getCoordinate() != null) {
	 * 		stmt.setString(6, address.getCoordinate().toString());
	 * 	}
	 * 
	 * 	stmt.executeUpdate();
	 * 
	 * 	stmt.close();
	 * 
	 * 	return lastGeneratedId();
	 * 
	 * }
	 * </pre>
	 * 
	 * 
	 *             public Long getIdByAddressCriteria(Address address) throws
	 *             SQLException, ClassNotFoundException {
	 * 
	 *             String select =
	 *             "SELECT ID FROM ADDRESS WHERE STREET = ? AND HOUSENUMBER = ? AND POSTALCODE = ? AND CITY = ? AND COUNTRYID = ?"
	 *             ; PreparedStatement stmt =
	 *             getConnection().getConnection().prepareStatement(select);
	 * 
	 *             stmt.setString(1, address.getStreet()); stmt.setString(2,
	 *             address.getHousenumber()); stmt.setString(3,
	 *             address.getPostalcode()); stmt.setString(4,
	 *             address.getCity()); stmt.setLong(5,
	 *             address.getCountry().getId());
	 * 
	 *             ResultSet result = stmt.executeQuery();
	 * 
	 *             if (result.next()) { return result.getLong(1); }
	 * 
	 *             return null; }
	 * 
	 *             public Address getById(Long id) throws SQLException,
	 *             ClassNotFoundException, ParseException {
	 * 
	 *             Statement stmt =
	 *             getConnection().getConnection().createStatement(); ResultSet
	 *             result = stmt .executeQuery(
	 *             "SELECT ID,STREET,HOUSENUMBER,POSTALCODE,CITY,COUNTRYID,ST_AsText(COORDINATES), CREATED FROM ADDRESS WHERE ID = "
	 *             + id);
	 * 
	 *             if (result.next()) { Address address =
	 *             extractAddressFromResult(result);
	 * 
	 *             return address; } return null; }
	 * 
	 *             public List<Address> getAll() throws SQLException,
	 *             ClassNotFoundException, ParseException {
	 * 
	 *             List<Address> addressList = new ArrayList<Address>();
	 *             Statement stmt =
	 *             getConnection().getConnection().createStatement(); ResultSet
	 *             result = stmt .executeQuery(
	 *             "SELECT ID,STREET,HOUSENUMBER,POSTALCODE,CITY,COUNTRYID,ST_AsText(COORDINATES), CREATED FROM ADDRESS"
	 *             );
	 * 
	 *             while (result.next()) { Address address =
	 *             extractAddressFromResult(result);
	 * 
	 *             addressList.add(address); }
	 * 
	 *             return addressList; }
	 * 
	 *             public Address extractAddressFromResult(ResultSet result)
	 *             throws SQLException, ClassNotFoundException, ParseException {
	 *             Address address = new Address();
	 *             address.setId(result.getLong(1));
	 *             address.setStreet(result.getString(2));
	 *             address.setHousenumber(result.getString(3));
	 *             address.setPostalcode(result.getString(4));
	 *             address.setCity(result.getString(5));
	 * 
	 *             Country country =
	 *             DaoFactory.getInstance().getCountryDAO().getById
	 *             (result.getLong(6)); address.setCountry(country);
	 * 
	 *             if (result.getString(7) != null) { Geometry coordinate =
	 *             GeoUtils.getPointFromText(result.getString(7));
	 *             address.setCoordinate(coordinate); }
	 * 
	 *             Calendar created = Calendar.getInstance();
	 *             created.setTime(result.getTime(8));
	 *             address.setCreated(created); return address; }
	 * 
	 *             public void updateCoordinate(Address address) throws
	 *             SQLException, ClassNotFoundException {
	 * 
	 *             String update =
	 *             "UPDATE ADDRESS SET COORDINATES = ST_GeomFromText(?,4326) WHERE ID = ?"
	 *             ; PreparedStatement stmt =
	 *             getConnection().getConnection().prepareStatement(update);
	 * 
	 *             Geometry point = address.getCoordinate(); stmt.setString(1,
	 *             point.toString()); stmt.setLong(2, address.getId());
	 * 
	 *             stmt.executeUpdate();
	 * 
	 *             stmt.close(); }
	 */

	/**
	 * Deleting a address is discouraged. DONT DO THAT!
	 * <p>
	 * It is used only for testing purposes.
	 * 
	 * @param persistedAddress
	 * @throws SQLException
	 * @throws ClassNotFoundException
	 *             <pre>
	 * public void delete(Address persistedAddress) throws SQLException, ClassNotFoundException {
	 * 
	 * 	Statement stmt = getConnection().getConnection().createStatement();
	 * 	stmt.executeUpdate(&quot;DELETE FROM ADDRESS WHERE ID = &quot; + persistedAddress.getId());
	 * 	System.err.println(&quot;WHY?&quot;);
	 * }
	 * </pre>
	 */

}
